Notes on approach


–Data wrangling–

  • The problem have asked to “develop a predictive model of the mean monthly Chl-a concentration in the California Bay Delta using other mean monthly water quality variables”. I interprested the ‘mean monthly’ values to be the mean value for a single month meaning that for each month of each year, there is one value which is the mean of all the values in that month. In this dataset, for example, for each variable there is one value for January 2005, one value for February 2005, and so on. This mean monthly value, therefore, was calculated by taking the mean values of all stations since the measurement for each station is collected monthly.
  • Since the predictive model is to predict Chl-a concentration using other mean monthly water quality variables, all other variables (columns) that are not water quality variables were removed. This leaves a dataset that only contains the response variable (mean monthly Chl-a) and the explanatory/predictor variables (mean monthly water quality variables). This dataset is then used to prepare datasets for problems 1 and 2.

–For problem 1–

  • A stepwise regression was used as the first step in selecting a model. Even though stepwise regression is somewhat a ‘black box’ approach, it is used because I did not want to use expert judgment (since I do not have sufficient expertise in water quality assessment) so stepwise regression was used to reduce the number of variables.
  • To explore parsimony, however, I did additional multiple correlations (pairwise simple correlation) to further reduce the number of variables in the model.
  • To compare the models, I mostly used the combination of the following values: adjusted R-squared, test statistic, AIC, BIC, and p-value.

–For problem 2–

  • The grouping of values into dry and wet season was done according to this article from the CA Department of Water Resources. The wet season is categorized as months where 90% of annual precipitation occurs which is from October to April. Meanwhile the dry season is categorized as the remaining months which is from May to September.

Data Wrangling


# load packages
library(tidyverse)
library(corrplot)
library(lubridate)
library(broom)
library(reshape2)
# load and check dataset
wq <- read_csv("BayDeltaWQ.csv",
               col_names = TRUE,
               na = c("NA", "n/p", "n/a"),
               guess_max = 30000)

|===                                                                                                           |   3%
|====                                                                                                          |   3%
|====                                                                                                          |   4%
|====                                                                                                          |   4%
|=====                                                                                                         |   4%
|=====                                                                                                         |   5%
|=====                                                                                                         |   5%
|======                                                                                                        |   5%
|======                                                                                                        |   5%
|======                                                                                                        |   6%
|=======                                                                                                       |   6%
|=======                                                                                                       |   6%
|========                                                                                                      |   7%
|========                                                                                                      |   7%
|========                                                                                                      |   7%
|=========                                                                                                     |   8%
|=========                                                                                                     |   8%
|=========                                                                                                     |   8%
|==========                                                                                                    |   9%
|==========                                                                                                    |   9%
|==========                                                                                                    |   9%
|===========                                                                                                   |  10%
|==========                                                                                            |  10%    1 MB
|==========                                                                                            |  10%    1 MB
|===========                                                                                           |  10%    1 MB
|===========                                                                                           |  11%    1 MB
|===========                                                                                           |  11%    1 MB
|============                                                                                          |  11%    1 MB
|============                                                                                          |  12%    1 MB
|============                                                                                          |  12%    1 MB
|=============                                                                                         |  12%    1 MB
|=============                                                                                         |  13%    1 MB
|=============                                                                                         |  13%    1 MB
|==============                                                                                        |  13%    1 MB
|==============                                                                                        |  14%    1 MB
|==============                                                                                        |  14%    1 MB
|===============                                                                                       |  14%    1 MB
|===============                                                                                       |  15%    1 MB
|===============                                                                                       |  15%    1 MB
|================                                                                                      |  15%    1 MB
|================                                                                                      |  16%    1 MB
|================                                                                                      |  16%    1 MB
|=================                                                                                     |  16%    1 MB
|=================                                                                                     |  16%    1 MB
|=================                                                                                     |  17%    1 MB
|==================                                                                                    |  17%    1 MB
|==================                                                                                    |  17%    1 MB
|==================                                                                                    |  18%    1 MB
|===================                                                                                   |  18%    1 MB
|===================                                                                                   |  18%    1 MB
|===================                                                                                   |  19%    1 MB
|====================                                                                                  |  19%    1 MB
|====================                                                                                  |  19%    1 MB
|====================                                                                                  |  20%    1 MB
|=====================                                                                                 |  20%    2 MB
|=====================                                                                                 |  20%    2 MB
|=====================                                                                                 |  21%    2 MB
|======================                                                                                |  21%    2 MB
|======================                                                                                |  21%    2 MB
|======================                                                                                |  22%    2 MB
|=======================                                                                               |  22%    2 MB
|=======================                                                                               |  22%    2 MB
|=======================                                                                               |  22%    2 MB
|=======================                                                                               |  23%    2 MB
|========================                                                                              |  23%    2 MB
|========================                                                                              |  23%    2 MB
|========================                                                                              |  24%    2 MB
|=========================                                                                             |  24%    2 MB
|=========================                                                                             |  24%    2 MB
|=========================                                                                             |  25%    2 MB
|==========================                                                                            |  25%    2 MB
|==========================                                                                            |  25%    2 MB
|==========================                                                                            |  26%    2 MB
|===========================                                                                           |  26%    2 MB
|===========================                                                                           |  26%    2 MB
|===========================                                                                           |  27%    2 MB
|============================                                                                          |  27%    2 MB
|============================                                                                          |  27%    2 MB
|============================                                                                          |  28%    2 MB
|=============================                                                                         |  28%    2 MB
|=============================                                                                         |  28%    2 MB
|=============================                                                                         |  28%    2 MB
|==============================                                                                        |  29%    2 MB
|==============================                                                                        |  29%    2 MB
|==============================                                                                        |  29%    2 MB
|===============================                                                                       |  30%    2 MB
|===============================                                                                       |  30%    3 MB
|===============================                                                                       |  30%    3 MB
|================================                                                                      |  31%    3 MB
|================================                                                                      |  31%    3 MB
|================================                                                                      |  31%    3 MB
|=================================                                                                     |  32%    3 MB
|=================================                                                                     |  32%    3 MB
|=================================                                                                     |  32%    3 MB
|==================================                                                                    |  33%    3 MB
|==================================                                                                    |  33%    3 MB
|==================================                                                                    |  33%    3 MB
|===================================                                                                   |  34%    3 MB
|===================================                                                                   |  34%    3 MB
|===================================                                                                   |  34%    3 MB
|====================================                                                                  |  34%    3 MB
|====================================                                                                  |  35%    3 MB
|====================================                                                                  |  35%    3 MB
|=====================================                                                                 |  35%    3 MB
|=====================================                                                                 |  36%    3 MB
|=====================================                                                                 |  36%    3 MB
|=====================================                                                                 |  36%    3 MB
|======================================                                                                |  37%    3 MB
|======================================                                                                |  37%    3 MB
|======================================                                                                |  37%    3 MB
|=======================================                                                               |  38%    3 MB
|=======================================                                                               |  38%    3 MB
|=======================================                                                               |  38%    3 MB
|========================================                                                              |  39%    3 MB
|========================================                                                              |  39%    3 MB
|========================================                                                              |  39%    3 MB
|=========================================                                                             |  40%    3 MB
|=========================================                                                             |  40%    3 MB
|=========================================                                                             |  40%    4 MB
|==========================================                                                            |  41%    4 MB
|==========================================                                                            |  41%    4 MB
|==========================================                                                            |  41%    4 MB
|===========================================                                                           |  42%    4 MB
|===========================================                                                           |  42%    4 MB
|===========================================                                                           |  42%    4 MB
|============================================                                                          |  42%    4 MB
|============================================                                                          |  43%    4 MB
|============================================                                                          |  43%    4 MB
|=============================================                                                         |  43%    4 MB
|=============================================                                                         |  44%    4 MB
|=============================================                                                         |  44%    4 MB
|==============================================                                                        |  44%    4 MB
|==============================================                                                        |  45%    4 MB
|==============================================                                                        |  45%    4 MB
|===============================================                                                       |  45%    4 MB
|===============================================                                                       |  46%    4 MB
|===============================================                                                       |  46%    4 MB
|================================================                                                      |  46%    4 MB
|================================================                                                      |  47%    4 MB
|================================================                                                      |  47%    4 MB
|=================================================                                                     |  47%    4 MB
|=================================================                                                     |  48%    4 MB
|=================================================                                                     |  48%    4 MB
|==================================================                                                    |  48%    4 MB
|==================================================                                                    |  49%    4 MB
|==================================================                                                    |  49%    4 MB
|===================================================                                                   |  49%    4 MB
|===================================================                                                   |  50%    4 MB
|===================================================                                                   |  50%    4 MB
|====================================================                                                  |  50%    4 MB
|====================================================                                                  |  50%    5 MB
|====================================================                                                  |  51%    5 MB
|=====================================================                                                 |  51%    5 MB
|=====================================================                                                 |  51%    5 MB
|=====================================================                                                 |  52%    5 MB
|======================================================                                                |  52%    5 MB
|======================================================                                                |  52%    5 MB
|======================================================                                                |  53%    5 MB
|=======================================================                                               |  53%    5 MB
|=======================================================                                               |  53%    5 MB
|=======================================================                                               |  54%    5 MB
|========================================================                                              |  54%    5 MB
|========================================================                                              |  54%    5 MB
|========================================================                                              |  55%    5 MB
|=========================================================                                             |  55%    5 MB
|=========================================================                                             |  55%    5 MB
|=========================================================                                             |  56%    5 MB
|==========================================================                                            |  56%    5 MB
|==========================================================                                            |  56%    5 MB
|==========================================================                                            |  57%    5 MB
|===========================================================                                           |  57%    5 MB
|===========================================================                                           |  57%    5 MB
|===========================================================                                           |  58%    5 MB
|============================================================                                          |  58%    5 MB
|============================================================                                          |  58%    5 MB
|============================================================                                          |  58%    5 MB
|=============================================================                                         |  59%    5 MB
|=============================================================                                         |  59%    5 MB
|=============================================================                                         |  59%    5 MB
|==============================================================                                        |  60%    5 MB
|==============================================================                                        |  60%    5 MB
|==============================================================                                        |  60%    6 MB
|===============================================================                                       |  61%    6 MB
|===============================================================                                       |  61%    6 MB
|===============================================================                                       |  61%    6 MB
|================================================================                                      |  62%    6 MB
|================================================================                                      |  62%    6 MB
|================================================================                                      |  62%    6 MB
|=================================================================                                     |  63%    6 MB
|=================================================================                                     |  63%    6 MB
|=================================================================                                     |  63%    6 MB
|==================================================================                                    |  64%    6 MB
|==================================================================                                    |  64%    6 MB
|==================================================================                                    |  64%    6 MB
|===================================================================                                   |  65%    6 MB
|===================================================================                                   |  65%    6 MB
|===================================================================                                   |  65%    6 MB
|====================================================================                                  |  66%    6 MB
|====================================================================                                  |  66%    6 MB
|====================================================================                                  |  66%    6 MB
|=====================================================================                                 |  67%    6 MB
|=====================================================================                                 |  67%    6 MB
|=====================================================================                                 |  67%    6 MB
|======================================================================                                |  67%    6 MB
|======================================================================                                |  68%    6 MB
|======================================================================                                |  68%    6 MB
|======================================================================                                |  68%    6 MB
|=======================================================================                               |  69%    6 MB
|=======================================================================                               |  69%    6 MB
|=======================================================================                               |  69%    6 MB
|========================================================================                              |  70%    6 MB
|========================================================================                              |  70%    6 MB
|========================================================================                              |  70%    6 MB
|=========================================================================                             |  71%    7 MB
|=========================================================================                             |  71%    7 MB
|=========================================================================                             |  71%    7 MB
|==========================================================================                            |  72%    7 MB
|==========================================================================                            |  72%    7 MB
|==========================================================================                            |  72%    7 MB
|===========================================================================                           |  73%    7 MB
|===========================================================================                           |  73%    7 MB
|===========================================================================                           |  73%    7 MB
|============================================================================                          |  74%    7 MB
|============================================================================                          |  74%    7 MB
|============================================================================                          |  74%    7 MB
|=============================================================================                         |  75%    7 MB
|=============================================================================                         |  75%    7 MB
|=============================================================================                         |  75%    7 MB
|==============================================================================                        |  75%    7 MB
|==============================================================================                        |  76%    7 MB
|==============================================================================                        |  76%    7 MB
|===============================================================================                       |  76%    7 MB
|===============================================================================                       |  77%    7 MB
|===============================================================================                       |  77%    7 MB
|================================================================================                      |  77%    7 MB
|================================================================================                      |  78%    7 MB
|================================================================================                      |  78%    7 MB
|=================================================================================                     |  78%    7 MB
|=================================================================================                     |  79%    7 MB
|=================================================================================                     |  79%    7 MB
|==================================================================================                    |  79%    7 MB
|==================================================================================                    |  80%    7 MB
|==================================================================================                    |  80%    7 MB
|===================================================================================                   |  80%    7 MB
|===================================================================================                   |  81%    7 MB
|===================================================================================                   |  81%    8 MB
|====================================================================================                  |  81%    8 MB
|====================================================================================                  |  82%    8 MB
|====================================================================================                  |  82%    8 MB
|=====================================================================================                 |  82%    8 MB
|=====================================================================================                 |  83%    8 MB
|=====================================================================================                 |  83%    8 MB
|======================================================================================                |  83%    8 MB
|======================================================================================                |  83%    8 MB
|======================================================================================                |  84%    8 MB
|=======================================================================================               |  84%    8 MB
|=======================================================================================               |  84%    8 MB
|=======================================================================================               |  85%    8 MB
|========================================================================================              |  85%    8 MB
|========================================================================================              |  85%    8 MB
|========================================================================================              |  86%    8 MB
|=========================================================================================             |  86%    8 MB
|=========================================================================================             |  86%    8 MB
|=========================================================================================             |  87%    8 MB
|==========================================================================================            |  87%    8 MB
|==========================================================================================            |  87%    8 MB
|==========================================================================================            |  88%    8 MB
|===========================================================================================           |  88%    8 MB
|===========================================================================================           |  88%    8 MB
|===========================================================================================           |  89%    8 MB
|============================================================================================          |  89%    8 MB
|============================================================================================          |  89%    8 MB
|============================================================================================          |  89%    8 MB
|=============================================================================================         |  90%    8 MB
|=============================================================================================         |  90%    8 MB
|=============================================================================================         |  90%    8 MB
|==============================================================================================        |  91%    8 MB
|==============================================================================================        |  91%    9 MB
|==============================================================================================        |  91%    9 MB
|==============================================================================================        |  92%    9 MB
|===============================================================================================       |  92%    9 MB
|===============================================================================================       |  92%    9 MB
|===============================================================================================       |  93%    9 MB
|================================================================================================      |  93%    9 MB
|================================================================================================      |  93%    9 MB
|================================================================================================      |  94%    9 MB
|=================================================================================================     |  94%    9 MB
|=================================================================================================     |  94%    9 MB
|=================================================================================================     |  95%    9 MB
|==================================================================================================    |  95%    9 MB
|==================================================================================================    |  95%    9 MB
|==================================================================================================    |  96%    9 MB
|===================================================================================================   |  96%    9 MB
|===================================================================================================   |  96%    9 MB
|===================================================================================================   |  96%    9 MB
|====================================================================================================  |  97%    9 MB
|====================================================================================================  |  97%    9 MB
|====================================================================================================  |  97%    9 MB
|===================================================================================================== |  98%    9 MB
|===================================================================================================== |  98%    9 MB
|===================================================================================================== |  98%    9 MB
|======================================================================================================|  99%    9 MB
|======================================================================================================|  99%    9 MB
|======================================================================================================|  99%    9 MB
|=======================================================================================================| 100%    9 MB
wq
# pull out month and year from SampleDate--
# to allow for grouping by year and month
wq_bymonth <- wq %>%
  mutate(Year = lubridate::year(SampleDate)) %>%    # add Year column
  mutate(Month = lubridate::month(SampleDate)) %>%  # add Month column
  group_by(Year, Month) %>%                         # # group rows by year and month
  select(Month, everything()) %>%                   # move Month column as 1st column
  select(Year, everything())                        # move Year column as 1st column
wq_bymonth
# filter rows to select only those sampled from--
# October 2004 to September 2012 (water years 2005-2012)
wq_bymonth <- wq_bymonth %>%
  #group_by(Year, Month) %>%               # group rows by year and month
  filter(Year > 2003) %>%                 # select observations after 2003
  filter(!(Year==2004 && Month<10)) %>%   # take out January-September 2004
  filter(!(Year==2012 && Month>9))        # take out October-December 2012
wq_bymonth
# summarize the column values to the mean monthly--
# so that each month in each year has a single value--
# which is the mean of all values in that month.
# this will result in 96 rows where each row is the--
# mean value for that month in that particular year--
# (12 months x 8 years = 96 months)
wq_meanmonthly <- wq_bymonth %>%
  summarise_if(is.numeric, mean, na.rm = TRUE) %>%
       # take the mean values of each month of--
       # each year only if the column type is a numeric
  select(-X1) %>%
       # take out index column (not useful)
  select(`Chlorophyll a`, everything())
       # move Chl-a column as first column
wq_meanmonthly

This wq_meanmonthly dataset is what will be used in preparing datasets for problems 1 and 2.


1| Predictive Model


–Data preparation

# remove NaN values
wq_meanmonthly_mod <- wq_meanmonthly %>%
  select_if(~sum(!is.na(.)) > 0) %>%
       # remove columns with values that are all NaN
  select_if(~sum(!is.na(.)) == nrow(wq_meanmonthly))
       # remove columns which have NaN values
wq_meanmonthly_mod
# remove variables that are not water quality variables
wq_meanmonthly_mod <- wq_meanmonthly_mod %>%
  ungroup() %>%
  select(-Year, -Month, -Depth)
wq_meanmonthly_mod

Now I will use the wq_meanmonthly_mod dataset for the model selection.

–Model selection

# use stepwise to reduce the number of variables
wq_step <- step(lm(`Chlorophyll a` ~ ., data = wq_meanmonthly_mod), trace = 0)
     # stepwise regression; trace = 0 returns only the final model of the stepwise
wq_step

Call:
lm(formula = `Chlorophyll a` ~ `Conductance (EC)` + Oxygen + 
    Temperature + `Ammonia (Dissolved)` + `Kjeldahl Nitrogen (Total)` + 
    `Organic Nitrogen (Dissolved)` + `Pheophytin a` + `Solids (Total Dissolved)`, 
    data = wq_meanmonthly_mod)

Coefficients:
                   (Intercept)              `Conductance (EC)`                          Oxygen  
                    -2.818e+01                      -3.190e-04                       2.288e+00  
                   Temperature           `Ammonia (Dissolved)`     `Kjeldahl Nitrogen (Total)`  
                     5.800e-01                      -8.995e+00                       6.765e+00  
`Organic Nitrogen (Dissolved)`                  `Pheophytin a`      `Solids (Total Dissolved)`  
                    -4.271e+00                       8.332e-01                       5.821e-04  
# the stepwise regression resulted in a model with--
# 8 predictor variables instead of the initial 19 variables
# make a new dataset containing only the 8 selected variables
wq_model <- select(wq_meanmonthly_mod,
                   `Chlorophyll a`,
                   `Conductance (EC)`,
                   Oxygen,
                   Temperature,
                   `Ammonia (Dissolved)`,
                   `Kjeldahl Nitrogen (Total)`,
                   `Organic Nitrogen (Dissolved)`,
                   `Pheophytin a`,
                   `Solids (Total Dissolved)`)
wq_model
# let's check if the model with 8 predictor variables is actually--
# better than with 19 predictor variables
lm_19v <- lm(`Chlorophyll a` ~ ., data = wq_meanmonthly_mod)
lm_8v <- lm(`Chlorophyll a` ~ ., data = wq_model)
lms <- list(w19v = lm_19v, w8v = lm_8v)
lms.stats <- mapply(glance, lms)
colnames(lms.stats) <- names(lms)
lms.stats
              w19v        w8v         
r.squared     0.6170207   0.5929971   
adj.r.squared 0.5212759   0.5555716   
sigma         1.594462    1.536287    
statistic     6.444429    15.84471    
p.value       1.66057e-09 3.569059e-14
df            20          9           
logLik        -169.7921   -172.7124   
AIC           381.5842    365.4247    
BIC           435.4355    391.0682    
deviance      193.2155    205.3356    
df.residual   76          87          

Although maybe not by much, the model from the stepwise regression (with 8 predictor variables) has a higher adj-r-square and test statistic with lower p-value, AIC, and BIC. From these values, the model with 8 predictor variables do seem to be better.

–Parsimony?

Having 8 predictor variables still sounds like a lot of variables. Let’s see if variable reduction can still be done by checking potential correlations between the predictor variables.

# --- (1) let's visualize the relationships between Chl-a and the 8 variables
plot(wq_model, pch=16, col="blue", cex = 0.5, main="Model: Chl-a ~ 8 variables")

From the plot, it looks like the following variables are potentially highly correlated:

  • Oxyen and Temperature
  • EC and Solids
  • Ammonia and Kjeldahl Nitrogen
  • Kjeldahl Nitrogen and Organic Nitrogen
# --- (2) let's check with correlation plot
mycor <- cor(wq_model)
cex.before <- par("cex")
par(cex = 0.7)
corrplot(mycor, method = "number", tl.cex = 1/par("cex"),
         cl.cex = 1/par("cex"))
par(cex = cex.before)

The correlation plot verifies that the following variables are highly correlated:

  • Oxyen x Temperature
  • EC x Solids
  • Ammonia x Kjeldahl Nitrogen
  • Kjeldahl Nitrogen x Organic Nitrogen
  • Temperature x Ammonia

Should some variables be removed? But which ones?

# --- (3) check regression summary to determine which variable to remove
chla_all <- lm(`Chlorophyll a` ~ ., data = wq_model)
summary(chla_all)

Call:
lm(formula = `Chlorophyll a` ~ ., data = wq_model)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.5837 -0.7604 -0.1729  0.5220  8.1688 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)                    -2.818e+01  7.968e+00  -3.536 0.000653 ***
`Conductance (EC)`             -3.190e-04  1.838e-04  -1.736 0.086158 .  
Oxygen                          2.288e+00  6.500e-01   3.519 0.000690 ***
Temperature                     5.800e-01  1.417e-01   4.092 9.52e-05 ***
`Ammonia (Dissolved)`          -8.995e+00  5.672e+00  -1.586 0.116359    
`Kjeldahl Nitrogen (Total)`     6.765e+00  2.741e+00   2.469 0.015522 *  
`Organic Nitrogen (Dissolved)` -4.271e+00  2.764e+00  -1.545 0.125911    
`Pheophytin a`                  8.332e-01  2.971e-01   2.804 0.006219 ** 
`Solids (Total Dissolved)`      5.821e-04  3.324e-04   1.751 0.083415 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.536 on 87 degrees of freedom
Multiple R-squared:  0.593, Adjusted R-squared:  0.5556 
F-statistic: 15.84 on 8 and 87 DF,  p-value: 3.569e-14

–Model comparison

Basing on the p-values and the variable correlations above:

  • The variables Oxygen, Organic Nitrogen, and Solids are removed while EC, Ammonia and Kjeldahl Nitrogen can also probably be removed.
  • Variables Temperature and Pheophytin a are both left in the models with 3 and 4 variables due to their low p-value and high correlation with Chl-a but they are not highly correlated with each other.
  • Since Temperature and Ammonia as well as Ammonia with Kjeldahl Nitrogen have relatively high correlations (-0.62 and 0.67 respectively), they are not included together in 3 and 4-variable models.

Let’s see if additional reduction improves the model by comparing the 8-variable model and some other models derived from combinations of the variables.

# --- null
chla_null <- lm(`Chlorophyll a` ~ 1, data = wq_model)
# --- all 8 variables
chla_all <- lm(`Chlorophyll a` ~ ., data = wq_model)
# --- 4 variables: EC, Temp, Kj N, Pheo a
chla_ec.tmp.kjn.phe <- lm(`Chlorophyll a` ~
                              `Conductance (EC)` +
                              Temperature +
                              `Kjeldahl Nitrogen (Total)` +
                              `Pheophytin a`,
                            data = wq_model)
# --- 3 variables: EC, Temp, Pheo a
#                  EC, Ammonia, Pheo a
#                  Temp, Kj N, Pheo a
chla_ec.tmp.phe <- lm(`Chlorophyll a` ~
                         `Conductance (EC)` +
                         Temperature +
                         `Pheophytin a`,
                       data = wq_model)
chla_ec.amm.phe <- lm(`Chlorophyll a` ~
                         `Conductance (EC)` +
                         `Ammonia (Dissolved)` +
                         `Pheophytin a`,
                       data = wq_model)
chla_tmp.kjn.phe <- lm(`Chlorophyll a` ~
                         Temperature +
                         `Kjeldahl Nitrogen (Total)` +
                         `Pheophytin a`,
                       data = wq_model)
# --- 2 variables: Temp and Pheo a
#                  Ammonia and Pheo a
#                  Kj N and Pheo a
#                  Temp and Kj N
chla_tmp.phe <- lm(`Chlorophyll a` ~
                      Temperature +
                      `Pheophytin a`,
                    data = wq_model)
chla_amm.phe <- lm(`Chlorophyll a` ~
                      `Ammonia (Dissolved)` +
                      `Pheophytin a`,
                    data = wq_model)
chla_kjn.phe <- lm(`Chlorophyll a` ~
                      `Kjeldahl Nitrogen (Total)` +
                      `Pheophytin a`,
                    data = wq_model)
chla_tmp.kjn <- lm(`Chlorophyll a` ~
                      Temperature +
                      `Kjeldahl Nitrogen (Total)`,
                    data = wq_model)
lms_compare <- list(null=chla_null,
                    all=chla_all,
                    ec.tmp.kjn.phe=chla_ec.tmp.kjn.phe,
                    ec.tmp.phe=chla_ec.tmp.phe,
                    ec.amm.phe=chla_ec.amm.phe,
                    tmp.kjn.phe=chla_tmp.kjn.phe,
                    tmp.phe=chla_tmp.phe,
                    amm.phe=chla_amm.phe,
                    kjn.phe=chla_kjn.phe,
                    tmp.kjn=chla_tmp.kjn)
lms_compare.stats <- mapply(glance, lms_compare)
colnames(lms_compare.stats) <- names(lms_compare)
lms_compare.stats
              null      all          ec.tmp.kjn.phe ec.tmp.phe   ec.amm.phe  tmp.kjn.phe  tmp.phe      amm.phe   
r.squared     0         0.5929971    0.4806624      0.4790654    0.4728065   0.4574591    0.4570602    0.4728041 
adj.r.squared 0         0.5555716    0.4578344      0.4620784    0.4556154   0.4397676    0.4453841    0.4614666 
sigma         2.304473  1.536287     1.696827       1.690173     1.700296    1.724867     1.716199     1.691133  
statistic     NA        15.84471     21.0558        28.20188     27.50299    25.85749     39.14486     41.70251  
p.value       NA        3.569059e-14 2.583643e-12   5.064252e-13 8.71719e-13 3.212171e-12 4.633964e-13 1.1795e-13
df            1         9            5              4            4           4            3            3         
logLik        -215.8612 -172.7124    -184.4116      -184.559     -185.1322   -186.5096    -186.5449    -185.1325 
AIC           435.7225  365.4247     380.8232       379.118      380.2645    383.0193     381.0898     378.2649  
BIC           440.8512  391.0682     396.2093       391.9397     393.0862    395.841      391.3472     388.5223  
deviance      504.5064  205.3356     262.0091       262.8148     265.9725    273.7153     273.9166     265.9737  
df.residual   95        87           91             92           92          92           93           93        
              kjn.phe      tmp.kjn     
r.squared     0.3863068    0.2691238   
adj.r.squared 0.3731091    0.253406    
sigma         1.824599     1.991195    
statistic     29.27076     17.12227    
p.value       1.379546e-10 4.663771e-07
df            3            3           
logLik        -192.4248    -200.8127   
AIC           392.8495     409.6254    
BIC           403.1069     419.8828    
deviance      309.6121     368.7317    
df.residual   93           93          

–Selected multiple regression model

By comparing the models above, the model with all 8 variables actually had the highest adj-r-squared value compared to the models with less predictor variables. However, in the case that fewer variables are available for measurement, I would select the following based on comparison of values of the adj-r-square, AIC/BIC, p-value, and test statistic.

  • the 3-variable model Chl-a ~ Ammonia + Pheophytin a

This model is able to explain 46% of the variation in Chl-a compared to 55% when using all 8 variables.

Let’s compare the residuals and predicted values for the model with 8 predictor variables and the model Chl-a ~ Ammonia + Pheophtin a.

# plot residuals
par(mfrow = c(2, 2))
plot(chla_all, pch = 16, which = 1)
plot(chla_all, pch = 16, which = 2)
plot(chla_amm.phe, pch = 16, which = 1)
plot(chla_amm.phe, pch = 16, which = 2)
par(mfrow = c(1, 1))

Top: all 8 variables; Bottom: Chl-a ~ Ammonia + Pheophytin a.

# plot predicted vs actual
par(mfrow = c(1, 2))
plot(predict(chla_all),wq_model$`Chlorophyll a`,
     xlab="predicted",ylab="actual", main ="Chl-a ~ .")
abline(a=0,b=1)
plot(predict(chla_amm.phe),wq_model$`Chlorophyll a`,
     xlab="predicted",ylab="actual", main ="Chl-a ~ Ammonia + Pheophytin a")
abline(a=0,b=1)
par(mfrow = c(1, 1))

–Best predictor

The selected multiple regression model has 2 variables. Is ther one best predictor for Chl-a concentration? I look at 3 variables: Temperature, Ammonia, and Pheophytin a. These 3 variables have the highest correlation value to Chl-a based on the correlation plot.

# lm for each of the 3 variables
chla_tmp <- lm(`Chlorophyll a` ~ Temperature, data = wq_model)
chla_amm <- lm(`Chlorophyll a` ~ `Ammonia (Dissolved)`, data = wq_model)
chla_phe <- lm(`Chlorophyll a` ~ `Pheophytin a`, data = wq_model)
# compare lms of the 3 variables
lms_best <- list(null=chla_null,
                    all=chla_all,
                    tmp=chla_tmp,
                    amm=chla_amm,
                    phe=chla_phe)
lms_best.stats <- mapply(glance, lms_best)
colnames(lms_best.stats) <- names(lms_best)
lms_best.stats
              null      all          tmp         amm          phe         
r.squared     0         0.5929971    0.2595211   0.1718766    0.3558155   
adj.r.squared 0         0.5555716    0.2516436   0.1630668    0.3489624   
sigma         2.304473  1.536287     1.993544    2.108225     1.859407    
statistic     NA        15.84471     32.94487    19.50966     51.92092    
p.value       NA        3.569059e-14 1.15385e-07 2.675906e-05 1.426426e-10
df            1         9            2           2            2           
logLik        -215.8612 -172.7124    -201.4393   -206.8088    -194.7523   
AIC           435.7225  365.4247     408.8785    419.6176     395.5046    
BIC           440.8512  391.0682     416.5716    427.3106     403.1976    
deviance      504.5064  205.3356     373.5763    417.7935     324.9952    
df.residual   95        87           94          94           94          

From the comparison, I would say that the most important variable explaining Chl-a is Pheophytin a which is able to explain 35% of the variability in Chl-a compared to 25% with Temperature and only 16% with Ammonia.

# plot residuals
par(mfrow=c(1,2))
plot(chla_phe, pch=16, which=1)
plot(chla_phe, pch=16, which=2)
par(mfrow=c(1,1))

The are somewhat normal and distributed along the 0 line although improvements may need to be done, such as investigation potential outliers (57, 45, and 3).

# plot predicted vs actual
plot(predict(chla_phe),wq_model$`Chlorophyll a`,
     xlab="predicted",ylab="actual", main = "Chl-a ~ Pheophytin a")
abline(a=0,b=1)

# plot Chl-a vs Pheophytin a actual values with prediction line from model
ggplot(wq_model, aes(x = `Pheophytin a`, y = `Chlorophyll a`)) +
  geom_point() +
  geom_line(aes(y = predict(chla_phe)), shape = 1)

The predicted values from the model are somewhat predicting the trend of the actual values.


2| Parallel Regression


–Data preparation

# add seasons
wq_meanmonthly_season <- wq_meanmonthly
wq_meanmonthly_season$Season <- ifelse(wq_meanmonthly_season$Month > 9 |
                                   wq_meanmonthly_season$Month < 5, "wet season", "dry season")
wq_season <- wq_meanmonthly_season %>%
  ungroup() %>%
  select(Season, everything()) %>%
  select(Month, everything()) %>%
  select(Year, everything())
wq_season$Season <- as.factor(wq_season$Season)
# create new dataset for parallel regression model
wq_prl_model <- select(wq_season,
                       `Chlorophyll a`,
                       Season,
                       `Pheophytin a`)

–Model comparison

# perform lms
# Chl-a ~ season
chla_season <- lm(`Chlorophyll a` ~ Season, data = wq_prl_model)
# Chl-a ~ Pheophytin a
chla_phea <- lm(`Chlorophyll a` ~ `Pheophytin a`, data = wq_prl_model)
# Chl-a ~ season + pheophytin a
chla_season.phea <- lm(`Chlorophyll a` ~ Season + `Pheophytin a`, data = wq_prl_model)
# compare models
lms_prl <- list(season=chla_season, phea=chla_phea, season.phea=chla_season.phea)
lms_prl.stats <- mapply(glance, lms_prl)
colnames(lms_prl.stats) <- names(lms_prl)
lms_prl.stats
              season      phea         season.phea 
r.squared     0.2360985   0.3558155    0.4413055   
adj.r.squared 0.2279719   0.3489624    0.4292905   
sigma         2.024828    1.859407     1.740921    
statistic     29.05251    51.92092     36.72974    
p.value       5.21002e-07 1.426426e-10 1.752311e-12
df            2           2            3           
logLik        -202.9341   -194.7523    -187.9179   
AIC           411.8681    395.5046     383.8359    
BIC           419.5612    403.1976     394.0933    
deviance      385.3932    324.9952     281.865     
df.residual   94          94           93          

The addition of the season category does seem to improve the model. The parallel model is able to explain 43% of the variation while the model with only Pheophytin a as the variable is only able to explain 35% of the variation.

–Residuals

# plot residuals
par(mfrow=c(2,3))
plot(chla_season, pch=16, which=1)
plot(chla_phea, pch=16, which=1)
plot(chla_season.phea, pch=16, which=1)
plot(chla_season, pch=16, which=2)
plot(chla_phea, pch=16, which=2)
plot(chla_season.phea, pch=16, which=2)
par(mfrow=c(1,1))

Left: Chl-a ~ season; Middle: Chl-a ~ Pheophytin a; Right: Parallel model.

–Plot

# extract intercept and slope values to generate regression lines
season_coef <- data.frame(t(coef(chla_season)))
colnames(season_coef) <- c("intercept", "slope")
season_coef
phea_coef <- data.frame(t(coef(chla_phea)))
colnames(phea_coef) <- c("intercept", "slope")
phea_coef
season.phea_coef <- data.frame(t(coef(chla_season.phea)))
colnames(season.phea_coef) <- c("intercept", "slope.season", "slope.phe")
season.phea_coef
# plot Chl-a vs Pheophytin a with regression lines
plot(wq_prl_model$`Pheophytin a`, wq_prl_model$`Chlorophyll a`, 
     xlab = "Pheophytin a",
     ylab = "Chlorophyll a",
     col = wq_prl_model$Season,
     pch = 16,
     main = "By Season (dry season: black, dry season: red)")
abline(reg = chla_phea, lty = 2)
abline(a = season.phea_coef$intercept, b = season.phea_coef$slope.phe, col = "blue")

The blue line is the regression line from the parallel model while the dashed black line is the regression line for the Chl-a ~ Pheophytin a model. Although not entirely clear from the plot, it seems as though the parallel model is accounting for for the dry season points compared to the univariate model. This may be because of the influence of the season variable in the parallel model. The plot also shows how the dry season may have a higher mean value than the wet season as it’s values seem to be higher than values from the wet season.


LS0tDQp0aXRsZTogIkhvbWV3b3JrIDcgKE11bHRpdmFyaWF0ZSBBbmFseXNlcykiDQphdXRob3I6ICJDaW5pbnRhIFBlcnRpd2kiDQpvdXRwdXQ6DQogIGdpdGh1Yl9kb2N1bWVudDoNCiAgICB0b2M6IG5vDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDUNCiAgICB0b2NfZmxvYXQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6ICc1Jw0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB5ZXMNCi0tLQ0KDQoqKioNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Tm90ZXMgb24gYXBwcm9hY2g8L3NwYW4+DQoqKioNCioqLS1EYXRhIHdyYW5nbGluZy0tKioNCg0KKiBUaGUgcHJvYmxlbSBoYXZlIGFza2VkIHRvICoiZGV2ZWxvcCBhIHByZWRpY3RpdmUgbW9kZWwgb2YgdGhlIG1lYW4gbW9udGhseSBDaGwtYSBjb25jZW50cmF0aW9uIGluIHRoZSBDYWxpZm9ybmlhIEJheSBEZWx0YSB1c2luZyBvdGhlciBtZWFuIG1vbnRobHkgd2F0ZXIgcXVhbGl0eSB2YXJpYWJsZXMiKi4gSSBpbnRlcnByZXN0ZWQgdGhlICdtZWFuIG1vbnRobHknIHZhbHVlcyB0byBiZSB0aGUgbWVhbiB2YWx1ZSBmb3IgYSBzaW5nbGUgbW9udGggbWVhbmluZyB0aGF0IGZvciBlYWNoIG1vbnRoIG9mIGVhY2ggeWVhciwgdGhlcmUgaXMgb25lIHZhbHVlIHdoaWNoIGlzIHRoZSBtZWFuIG9mIGFsbCB0aGUgdmFsdWVzIGluIHRoYXQgbW9udGguIEluIHRoaXMgZGF0YXNldCwgZm9yIGV4YW1wbGUsIGZvciBlYWNoIHZhcmlhYmxlIHRoZXJlIGlzIG9uZSB2YWx1ZSBmb3IgSmFudWFyeSAyMDA1LCBvbmUgdmFsdWUgZm9yIEZlYnJ1YXJ5IDIwMDUsIGFuZCBzbyBvbi4gVGhpcyBtZWFuIG1vbnRobHkgdmFsdWUsIHRoZXJlZm9yZSwgd2FzIGNhbGN1bGF0ZWQgYnkgdGFraW5nIHRoZSBtZWFuIHZhbHVlcyBvZiBhbGwgc3RhdGlvbnMgc2luY2UgdGhlIG1lYXN1cmVtZW50IGZvciBlYWNoIHN0YXRpb24gaXMgY29sbGVjdGVkIG1vbnRobHkuDQoqIFNpbmNlIHRoZSBwcmVkaWN0aXZlIG1vZGVsIGlzIHRvIHByZWRpY3QgQ2hsLWEgY29uY2VudHJhdGlvbiB1c2luZyBvdGhlciBtZWFuIG1vbnRobHkgd2F0ZXIgcXVhbGl0eSB2YXJpYWJsZXMsIGFsbCBvdGhlciB2YXJpYWJsZXMgKGNvbHVtbnMpIHRoYXQgYXJlIG5vdCB3YXRlciBxdWFsaXR5IHZhcmlhYmxlcyB3ZXJlIHJlbW92ZWQuIFRoaXMgbGVhdmVzIGEgZGF0YXNldCB0aGF0IG9ubHkgY29udGFpbnMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIChtZWFuIG1vbnRobHkgQ2hsLWEpIGFuZCB0aGUgZXhwbGFuYXRvcnkvcHJlZGljdG9yIHZhcmlhYmxlcyAobWVhbiBtb250aGx5IHdhdGVyIHF1YWxpdHkgdmFyaWFibGVzKS4gVGhpcyBkYXRhc2V0IGlzIHRoZW4gdXNlZCB0byBwcmVwYXJlIGRhdGFzZXRzIGZvciBwcm9ibGVtcyAxIGFuZCAyLg0KDQoqKi0tRm9yIHByb2JsZW0gMS0tKioNCg0KKiBBIHN0ZXB3aXNlIHJlZ3Jlc3Npb24gd2FzIHVzZWQgYXMgdGhlIGZpcnN0IHN0ZXAgaW4gc2VsZWN0aW5nIGEgbW9kZWwuIEV2ZW4gdGhvdWdoIHN0ZXB3aXNlIHJlZ3Jlc3Npb24gaXMgc29tZXdoYXQgYSAnYmxhY2sgYm94JyBhcHByb2FjaCwgaXQgaXMgdXNlZCBiZWNhdXNlIEkgZGlkIG5vdCB3YW50IHRvIHVzZSBleHBlcnQganVkZ21lbnQgKHNpbmNlIEkgZG8gbm90IGhhdmUgc3VmZmljaWVudCBleHBlcnRpc2UgaW4gd2F0ZXIgcXVhbGl0eSBhc3Nlc3NtZW50KSBzbyBzdGVwd2lzZSByZWdyZXNzaW9uIHdhcyB1c2VkIHRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHZhcmlhYmxlcy4NCiogVG8gZXhwbG9yZSBwYXJzaW1vbnksIGhvd2V2ZXIsIEkgZGlkIGFkZGl0aW9uYWwgbXVsdGlwbGUgY29ycmVsYXRpb25zIChwYWlyd2lzZSBzaW1wbGUgY29ycmVsYXRpb24pIHRvIGZ1cnRoZXIgcmVkdWNlIHRoZSBudW1iZXIgb2YgdmFyaWFibGVzIGluIHRoZSBtb2RlbC4NCiogVG8gY29tcGFyZSB0aGUgbW9kZWxzLCBJIG1vc3RseSB1c2VkIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczogYWRqdXN0ZWQgUi1zcXVhcmVkLCB0ZXN0IHN0YXRpc3RpYywgQUlDLCBCSUMsIGFuZCBwLXZhbHVlLg0KDQoqKi0tRm9yIHByb2JsZW0gMi0tKioNCg0KKiBUaGUgZ3JvdXBpbmcgb2YgdmFsdWVzIGludG8gZHJ5IGFuZCB3ZXQgc2Vhc29uIHdhcyBkb25lIGFjY29yZGluZyBbdG8gdGhpcyBhcnRpY2xlXShodHRwczovL3d3dy53YXRlci5jYS5nb3YvTGVnYWN5RmlsZXMvZmxvb2RtZ210L2hhZm9vL2NzYy9kb2NzL0NBX1ByZWNpcGl0YXRpb25fMnBhZ2VyLnBkZikgZnJvbSB0aGUgQ0EgRGVwYXJ0bWVudCBvZiBXYXRlciBSZXNvdXJjZXMuIFRoZSAqKndldCBzZWFzb24qKiBpcyBjYXRlZ29yaXplZCBhcyBtb250aHMgd2hlcmUgOTAlIG9mIGFubnVhbCBwcmVjaXBpdGF0aW9uIG9jY3VycyB3aGljaCBpcyBmcm9tIE9jdG9iZXIgdG8gQXByaWwuIE1lYW53aGlsZSB0aGUgKipkcnkgc2Vhc29uKiogaXMgY2F0ZWdvcml6ZWQgYXMgdGhlIHJlbWFpbmluZyBtb250aHMgd2hpY2ggaXMgZnJvbSBNYXkgdG8gU2VwdGVtYmVyLg0KDQoqKioNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+RGF0YSBXcmFuZ2xpbmc8L3NwYW4+DQoqKioNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgbG9hZCBwYWNrYWdlcw0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGxvYWQgYW5kIGNoZWNrIGRhdGFzZXQNCg0Kd3EgPC0gcmVhZF9jc3YoIkJheURlbHRhV1EuY3N2IiwNCiAgICAgICAgICAgICAgIGNvbF9uYW1lcyA9IFRSVUUsDQogICAgICAgICAgICAgICBuYSA9IGMoIk5BIiwgIm4vcCIsICJuL2EiKSwNCiAgICAgICAgICAgICAgIGd1ZXNzX21heCA9IDMwMDAwKQ0Kd3ENCmBgYA0KDQoNCmBgYHtyfQ0KIyBwdWxsIG91dCBtb250aCBhbmQgeWVhciBmcm9tIFNhbXBsZURhdGUtLQ0KIyB0byBhbGxvdyBmb3IgZ3JvdXBpbmcgYnkgeWVhciBhbmQgbW9udGgNCg0Kd3FfYnltb250aCA8LSB3cSAlPiUNCiAgbXV0YXRlKFllYXIgPSBsdWJyaWRhdGU6OnllYXIoU2FtcGxlRGF0ZSkpICU+JSAgICAjIGFkZCBZZWFyIGNvbHVtbg0KICBtdXRhdGUoTW9udGggPSBsdWJyaWRhdGU6Om1vbnRoKFNhbXBsZURhdGUpKSAlPiUgICMgYWRkIE1vbnRoIGNvbHVtbg0KICBncm91cF9ieShZZWFyLCBNb250aCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICMgIyBncm91cCByb3dzIGJ5IHllYXIgYW5kIG1vbnRoDQogIHNlbGVjdChNb250aCwgZXZlcnl0aGluZygpKSAlPiUgICAgICAgICAgICAgICAgICAgIyBtb3ZlIE1vbnRoIGNvbHVtbiBhcyAxc3QgY29sdW1uDQogIHNlbGVjdChZZWFyLCBldmVyeXRoaW5nKCkpICAgICAgICAgICAgICAgICAgICAgICAgIyBtb3ZlIFllYXIgY29sdW1uIGFzIDFzdCBjb2x1bW4NCndxX2J5bW9udGgNCmBgYA0KDQpgYGB7cn0NCiMgZmlsdGVyIHJvd3MgdG8gc2VsZWN0IG9ubHkgdGhvc2Ugc2FtcGxlZCBmcm9tLS0NCiMgT2N0b2JlciAyMDA0IHRvIFNlcHRlbWJlciAyMDEyICh3YXRlciB5ZWFycyAyMDA1LTIwMTIpDQoNCndxX2J5bW9udGggPC0gd3FfYnltb250aCAlPiUNCiAgI2dyb3VwX2J5KFllYXIsIE1vbnRoKSAlPiUgICAgICAgICAgICAgICAjIGdyb3VwIHJvd3MgYnkgeWVhciBhbmQgbW9udGgNCiAgZmlsdGVyKFllYXIgPiAyMDAzKSAlPiUgICAgICAgICAgICAgICAgICMgc2VsZWN0IG9ic2VydmF0aW9ucyBhZnRlciAyMDAzDQogIGZpbHRlcighKFllYXI9PTIwMDQgJiYgTW9udGg8MTApKSAlPiUgICAjIHRha2Ugb3V0IEphbnVhcnktU2VwdGVtYmVyIDIwMDQNCiAgZmlsdGVyKCEoWWVhcj09MjAxMiAmJiBNb250aD45KSkgICAgICAgICMgdGFrZSBvdXQgT2N0b2Jlci1EZWNlbWJlciAyMDEyDQp3cV9ieW1vbnRoDQpgYGANCg0KYGBge3J9DQojIHN1bW1hcml6ZSB0aGUgY29sdW1uIHZhbHVlcyB0byB0aGUgbWVhbiBtb250aGx5LS0NCiMgc28gdGhhdCBlYWNoIG1vbnRoIGluIGVhY2ggeWVhciBoYXMgYSBzaW5nbGUgdmFsdWUtLQ0KIyB3aGljaCBpcyB0aGUgbWVhbiBvZiBhbGwgdmFsdWVzIGluIHRoYXQgbW9udGguDQojIHRoaXMgd2lsbCByZXN1bHQgaW4gOTYgcm93cyB3aGVyZSBlYWNoIHJvdyBpcyB0aGUtLQ0KIyBtZWFuIHZhbHVlIGZvciB0aGF0IG1vbnRoIGluIHRoYXQgcGFydGljdWxhciB5ZWFyLS0NCiMgKDEyIG1vbnRocyB4IDggeWVhcnMgPSA5NiBtb250aHMpDQoNCndxX21lYW5tb250aGx5IDwtIHdxX2J5bW9udGggJT4lDQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpICU+JQ0KICAgICAgICMgdGFrZSB0aGUgbWVhbiB2YWx1ZXMgb2YgZWFjaCBtb250aCBvZi0tDQogICAgICAgIyBlYWNoIHllYXIgb25seSBpZiB0aGUgY29sdW1uIHR5cGUgaXMgYSBudW1lcmljDQogIHNlbGVjdCgtWDEpICU+JQ0KICAgICAgICMgdGFrZSBvdXQgaW5kZXggY29sdW1uIChub3QgdXNlZnVsKQ0KICBzZWxlY3QoYENobG9yb3BoeWxsIGFgLCBldmVyeXRoaW5nKCkpDQogICAgICAgIyBtb3ZlIENobC1hIGNvbHVtbiBhcyBmaXJzdCBjb2x1bW4NCndxX21lYW5tb250aGx5DQpgYGANCg0KVGhpcyBgd3FfbWVhbm1vbnRobHlgIGRhdGFzZXQgaXMgd2hhdCB3aWxsIGJlIHVzZWQgaW4gcHJlcGFyaW5nIGRhdGFzZXRzIGZvciBwcm9ibGVtcyAxIGFuZCAyLg0KDQoqKioNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+MXwgUHJlZGljdGl2ZSBNb2RlbDwvc3Bhbj4NCioqKg0KDQojIyMjICoqLS1EYXRhIHByZXBhcmF0aW9uKioNCmBgYHtyfQ0KIyByZW1vdmUgTmFOIHZhbHVlcw0KDQp3cV9tZWFubW9udGhseV9tb2QgPC0gd3FfbWVhbm1vbnRobHkgJT4lDQogIHNlbGVjdF9pZih+c3VtKCFpcy5uYSguKSkgPiAwKSAlPiUNCiAgICAgICAjIHJlbW92ZSBjb2x1bW5zIHdpdGggdmFsdWVzIHRoYXQgYXJlIGFsbCBOYU4NCiAgc2VsZWN0X2lmKH5zdW0oIWlzLm5hKC4pKSA9PSBucm93KHdxX21lYW5tb250aGx5KSkNCiAgICAgICAjIHJlbW92ZSBjb2x1bW5zIHdoaWNoIGhhdmUgTmFOIHZhbHVlcw0Kd3FfbWVhbm1vbnRobHlfbW9kDQpgYGANCg0KYGBge3J9DQojIHJlbW92ZSB2YXJpYWJsZXMgdGhhdCBhcmUgbm90IHdhdGVyIHF1YWxpdHkgdmFyaWFibGVzDQoNCndxX21lYW5tb250aGx5X21vZCA8LSB3cV9tZWFubW9udGhseV9tb2QgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgc2VsZWN0KC1ZZWFyLCAtTW9udGgsIC1EZXB0aCkNCndxX21lYW5tb250aGx5X21vZA0KYGBgDQoNCk5vdyBJIHdpbGwgdXNlIHRoZSBgd3FfbWVhbm1vbnRobHlfbW9kYCBkYXRhc2V0IGZvciB0aGUgbW9kZWwgc2VsZWN0aW9uLg0KDQojIyMjICoqLS1Nb2RlbCBzZWxlY3Rpb24qKg0KYGBge3J9DQojIHVzZSBzdGVwd2lzZSB0byByZWR1Y2UgdGhlIG51bWJlciBvZiB2YXJpYWJsZXMNCg0Kd3Ffc3RlcCA8LSBzdGVwKGxtKGBDaGxvcm9waHlsbCBhYCB+IC4sIGRhdGEgPSB3cV9tZWFubW9udGhseV9tb2QpLCB0cmFjZSA9IDApDQogICAgICMgc3RlcHdpc2UgcmVncmVzc2lvbjsgdHJhY2UgPSAwIHJldHVybnMgb25seSB0aGUgZmluYWwgbW9kZWwgb2YgdGhlIHN0ZXB3aXNlDQp3cV9zdGVwDQpgYGANCg0KYGBge3J9DQojIHRoZSBzdGVwd2lzZSByZWdyZXNzaW9uIHJlc3VsdGVkIGluIGEgbW9kZWwgd2l0aC0tDQojIDggcHJlZGljdG9yIHZhcmlhYmxlcyBpbnN0ZWFkIG9mIHRoZSBpbml0aWFsIDE5IHZhcmlhYmxlcw0KDQojIG1ha2UgYSBuZXcgZGF0YXNldCBjb250YWluaW5nIG9ubHkgdGhlIDggc2VsZWN0ZWQgdmFyaWFibGVzDQoNCndxX21vZGVsIDwtIHNlbGVjdCh3cV9tZWFubW9udGhseV9tb2QsDQogICAgICAgICAgICAgICAgICAgYENobG9yb3BoeWxsIGFgLA0KICAgICAgICAgICAgICAgICAgIGBDb25kdWN0YW5jZSAoRUMpYCwNCiAgICAgICAgICAgICAgICAgICBPeHlnZW4sDQogICAgICAgICAgICAgICAgICAgVGVtcGVyYXR1cmUsDQogICAgICAgICAgICAgICAgICAgYEFtbW9uaWEgKERpc3NvbHZlZClgLA0KICAgICAgICAgICAgICAgICAgIGBLamVsZGFobCBOaXRyb2dlbiAoVG90YWwpYCwNCiAgICAgICAgICAgICAgICAgICBgT3JnYW5pYyBOaXRyb2dlbiAoRGlzc29sdmVkKWAsDQogICAgICAgICAgICAgICAgICAgYFBoZW9waHl0aW4gYWAsDQogICAgICAgICAgICAgICAgICAgYFNvbGlkcyAoVG90YWwgRGlzc29sdmVkKWApDQp3cV9tb2RlbA0KYGBgDQoNCmBgYHtyfQ0KIyBsZXQncyBjaGVjayBpZiB0aGUgbW9kZWwgd2l0aCA4IHByZWRpY3RvciB2YXJpYWJsZXMgaXMgYWN0dWFsbHktLQ0KIyBiZXR0ZXIgdGhhbiB3aXRoIDE5IHByZWRpY3RvciB2YXJpYWJsZXMNCg0KbG1fMTl2IDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+IC4sIGRhdGEgPSB3cV9tZWFubW9udGhseV9tb2QpDQpsbV84diA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfiAuLCBkYXRhID0gd3FfbW9kZWwpDQoNCmxtcyA8LSBsaXN0KHcxOXYgPSBsbV8xOXYsIHc4diA9IGxtXzh2KQ0KbG1zLnN0YXRzIDwtIG1hcHBseShnbGFuY2UsIGxtcykNCmNvbG5hbWVzKGxtcy5zdGF0cykgPC0gbmFtZXMobG1zKQ0KbG1zLnN0YXRzDQpgYGANCkFsdGhvdWdoIG1heWJlIG5vdCBieSBtdWNoLCB0aGUgbW9kZWwgZnJvbSB0aGUgc3RlcHdpc2UgcmVncmVzc2lvbiAod2l0aCA4IHByZWRpY3RvciB2YXJpYWJsZXMpIGhhcyBhIGhpZ2hlciBhZGotci1zcXVhcmUgYW5kIHRlc3Qgc3RhdGlzdGljIHdpdGggbG93ZXIgcC12YWx1ZSwgQUlDLCBhbmQgQklDLiBGcm9tIHRoZXNlIHZhbHVlcywgdGhlIG1vZGVsIHdpdGggOCBwcmVkaWN0b3IgdmFyaWFibGVzIGRvIHNlZW0gdG8gYmUgYmV0dGVyLg0KDQojIyMjICoqLS1QYXJzaW1vbnk/KioNCkhhdmluZyA4IHByZWRpY3RvciB2YXJpYWJsZXMgc3RpbGwgc291bmRzIGxpa2UgYSBsb3Qgb2YgdmFyaWFibGVzLiBMZXQncyBzZWUgaWYgdmFyaWFibGUgcmVkdWN0aW9uIGNhbiBzdGlsbCBiZSBkb25lIGJ5IGNoZWNraW5nIHBvdGVudGlhbCBjb3JyZWxhdGlvbnMgYmV0d2VlbiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcy4NCmBgYHtyfQ0KIyAtLS0gKDEpIGxldCdzIHZpc3VhbGl6ZSB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIENobC1hIGFuZCB0aGUgOCB2YXJpYWJsZXMNCg0KcGxvdCh3cV9tb2RlbCwgcGNoPTE2LCBjb2w9ImJsdWUiLCBjZXggPSAwLjUsIG1haW49Ik1vZGVsOiBDaGwtYSB+IDggdmFyaWFibGVzIikNCmBgYA0KDQpGcm9tIHRoZSBwbG90LCBpdCBsb29rcyBsaWtlIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGFyZSBwb3RlbnRpYWxseSBoaWdobHkgY29ycmVsYXRlZDoNCg0KKiBPeHllbiBhbmQgVGVtcGVyYXR1cmUNCiogRUMgYW5kIFNvbGlkcw0KKiBBbW1vbmlhIGFuZCBLamVsZGFobCBOaXRyb2dlbg0KKiBLamVsZGFobCBOaXRyb2dlbiBhbmQgT3JnYW5pYyBOaXRyb2dlbg0KDQpgYGB7cn0NCiMgLS0tICgyKSBsZXQncyBjaGVjayB3aXRoIGNvcnJlbGF0aW9uIHBsb3QNCg0KbXljb3IgPC0gY29yKHdxX21vZGVsKQ0KDQpjZXguYmVmb3JlIDwtIHBhcigiY2V4IikNCnBhcihjZXggPSAwLjcpDQoNCmNvcnJwbG90KG15Y29yLCBtZXRob2QgPSAibnVtYmVyIiwgdGwuY2V4ID0gMS9wYXIoImNleCIpLA0KICAgICAgICAgY2wuY2V4ID0gMS9wYXIoImNleCIpKQ0KDQpwYXIoY2V4ID0gY2V4LmJlZm9yZSkNCmBgYA0KDQpUaGUgY29ycmVsYXRpb24gcGxvdCB2ZXJpZmllcyB0aGF0IHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGFyZSBoaWdobHkgY29ycmVsYXRlZDoNCg0KKiBPeHllbiB4IFRlbXBlcmF0dXJlDQoqIEVDIHggU29saWRzDQoqIEFtbW9uaWEgeCBLamVsZGFobCBOaXRyb2dlbg0KKiBLamVsZGFobCBOaXRyb2dlbiB4IE9yZ2FuaWMgTml0cm9nZW4NCiogVGVtcGVyYXR1cmUgeCBBbW1vbmlhDQoNClNob3VsZCBzb21lIHZhcmlhYmxlcyBiZSByZW1vdmVkPyBCdXQgd2hpY2ggb25lcz8NCmBgYHtyfQ0KIyAtLS0gKDMpIGNoZWNrIHJlZ3Jlc3Npb24gc3VtbWFyeSB0byBkZXRlcm1pbmUgd2hpY2ggdmFyaWFibGUgdG8gcmVtb3ZlDQoNCmNobGFfYWxsIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+IC4sIGRhdGEgPSB3cV9tb2RlbCkNCnN1bW1hcnkoY2hsYV9hbGwpDQpgYGANCg0KDQojIyMjICoqLS1Nb2RlbCBjb21wYXJpc29uKioNCg0KQmFzaW5nIG9uIHRoZSBwLXZhbHVlcyBhbmQgdGhlIHZhcmlhYmxlIGNvcnJlbGF0aW9ucyBhYm92ZToNCg0KKiBUaGUgdmFyaWFibGVzIE94eWdlbiwgT3JnYW5pYyBOaXRyb2dlbiwgYW5kIFNvbGlkcyBhcmUgcmVtb3ZlZCB3aGlsZSBFQywgQW1tb25pYSBhbmQgS2plbGRhaGwgTml0cm9nZW4gY2FuIGFsc28gcHJvYmFibHkgYmUgcmVtb3ZlZC4NCiogVmFyaWFibGVzIFRlbXBlcmF0dXJlIGFuZCBQaGVvcGh5dGluIGEgYXJlIGJvdGggbGVmdCBpbiB0aGUgbW9kZWxzIHdpdGggMyBhbmQgNCB2YXJpYWJsZXMgZHVlIHRvIHRoZWlyIGxvdyBwLXZhbHVlIGFuZCBoaWdoIGNvcnJlbGF0aW9uIHdpdGggQ2hsLWEgYnV0IHRoZXkgYXJlIG5vdCBoaWdobHkgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuDQoqIFNpbmNlIFRlbXBlcmF0dXJlIGFuZCBBbW1vbmlhIGFzIHdlbGwgYXMgQW1tb25pYSB3aXRoIEtqZWxkYWhsIE5pdHJvZ2VuIGhhdmUgcmVsYXRpdmVseSBoaWdoIGNvcnJlbGF0aW9ucyAoLTAuNjIgYW5kIDAuNjcgcmVzcGVjdGl2ZWx5KSwgdGhleSBhcmUgbm90IGluY2x1ZGVkIHRvZ2V0aGVyIGluIDMgYW5kIDQtdmFyaWFibGUgbW9kZWxzLg0KDQpMZXQncyBzZWUgaWYgYWRkaXRpb25hbCByZWR1Y3Rpb24gaW1wcm92ZXMgdGhlIG1vZGVsIGJ5IGNvbXBhcmluZyB0aGUgOC12YXJpYWJsZSBtb2RlbCBhbmQgc29tZSBvdGhlciBtb2RlbHMgZGVyaXZlZCBmcm9tIGNvbWJpbmF0aW9ucyBvZiB0aGUgdmFyaWFibGVzLg0KDQpgYGB7cn0NCiMgLS0tIG51bGwNCmNobGFfbnVsbCA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfiAxLCBkYXRhID0gd3FfbW9kZWwpDQoNCiMgLS0tIGFsbCA4IHZhcmlhYmxlcw0KY2hsYV9hbGwgPC0gbG0oYENobG9yb3BoeWxsIGFgIH4gLiwgZGF0YSA9IHdxX21vZGVsKQ0KYGBgDQoNCmBgYHtyfQ0KIyAtLS0gNCB2YXJpYWJsZXM6IEVDLCBUZW1wLCBLaiBOLCBQaGVvIGENCg0KY2hsYV9lYy50bXAua2puLnBoZSA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYENvbmR1Y3RhbmNlIChFQylgICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRlbXBlcmF0dXJlICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBLamVsZGFobCBOaXRyb2dlbiAoVG90YWwpYCArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgUGhlb3BoeXRpbiBhYCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gd3FfbW9kZWwpDQpgYGANCg0KYGBge3J9DQojIC0tLSAzIHZhcmlhYmxlczogRUMsIFRlbXAsIFBoZW8gYQ0KIyAgICAgICAgICAgICAgICAgIEVDLCBBbW1vbmlhLCBQaGVvIGENCiMgICAgICAgICAgICAgICAgICBUZW1wLCBLaiBOLCBQaGVvIGENCg0KY2hsYV9lYy50bXAucGhlIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+DQogICAgICAgICAgICAgICAgICAgICAgICAgYENvbmR1Y3RhbmNlIChFQylgICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBUZW1wZXJhdHVyZSArDQogICAgICAgICAgICAgICAgICAgICAgICAgYFBoZW9waHl0aW4gYWAsDQogICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB3cV9tb2RlbCkNCmNobGFfZWMuYW1tLnBoZSA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfg0KICAgICAgICAgICAgICAgICAgICAgICAgIGBDb25kdWN0YW5jZSAoRUMpYCArDQogICAgICAgICAgICAgICAgICAgICAgICAgYEFtbW9uaWEgKERpc3NvbHZlZClgICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBgUGhlb3BoeXRpbiBhYCwNCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHdxX21vZGVsKQ0KY2hsYV90bXAua2puLnBoZSA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfg0KICAgICAgICAgICAgICAgICAgICAgICAgIFRlbXBlcmF0dXJlICsNCiAgICAgICAgICAgICAgICAgICAgICAgICBgS2plbGRhaGwgTml0cm9nZW4gKFRvdGFsKWAgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIGBQaGVvcGh5dGluIGFgLA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gd3FfbW9kZWwpDQoNCmBgYA0KDQpgYGB7cn0NCiMgLS0tIDIgdmFyaWFibGVzOiBUZW1wIGFuZCBQaGVvIGENCiMgICAgICAgICAgICAgICAgICBBbW1vbmlhIGFuZCBQaGVvIGENCiMgICAgICAgICAgICAgICAgICBLaiBOIGFuZCBQaGVvIGENCiMgICAgICAgICAgICAgICAgICBUZW1wIGFuZCBLaiBODQoNCmNobGFfdG1wLnBoZSA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfg0KICAgICAgICAgICAgICAgICAgICAgIFRlbXBlcmF0dXJlICsNCiAgICAgICAgICAgICAgICAgICAgICBgUGhlb3BoeXRpbiBhYCwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHdxX21vZGVsKQ0KY2hsYV9hbW0ucGhlIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+DQogICAgICAgICAgICAgICAgICAgICAgYEFtbW9uaWEgKERpc3NvbHZlZClgICsNCiAgICAgICAgICAgICAgICAgICAgICBgUGhlb3BoeXRpbiBhYCwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHdxX21vZGVsKQ0KY2hsYV9ram4ucGhlIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+DQogICAgICAgICAgICAgICAgICAgICAgYEtqZWxkYWhsIE5pdHJvZ2VuIChUb3RhbClgICsNCiAgICAgICAgICAgICAgICAgICAgICBgUGhlb3BoeXRpbiBhYCwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHdxX21vZGVsKQ0KY2hsYV90bXAua2puIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+DQogICAgICAgICAgICAgICAgICAgICAgVGVtcGVyYXR1cmUgKw0KICAgICAgICAgICAgICAgICAgICAgIGBLamVsZGFobCBOaXRyb2dlbiAoVG90YWwpYCwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHdxX21vZGVsKQ0KYGBgDQoNCmBgYHtyfQ0KDQpsbXNfY29tcGFyZSA8LSBsaXN0KG51bGw9Y2hsYV9udWxsLA0KICAgICAgICAgICAgICAgICAgICBhbGw9Y2hsYV9hbGwsDQogICAgICAgICAgICAgICAgICAgIGVjLnRtcC5ram4ucGhlPWNobGFfZWMudG1wLmtqbi5waGUsDQogICAgICAgICAgICAgICAgICAgIGVjLnRtcC5waGU9Y2hsYV9lYy50bXAucGhlLA0KICAgICAgICAgICAgICAgICAgICBlYy5hbW0ucGhlPWNobGFfZWMuYW1tLnBoZSwNCiAgICAgICAgICAgICAgICAgICAgdG1wLmtqbi5waGU9Y2hsYV90bXAua2puLnBoZSwNCiAgICAgICAgICAgICAgICAgICAgdG1wLnBoZT1jaGxhX3RtcC5waGUsDQogICAgICAgICAgICAgICAgICAgIGFtbS5waGU9Y2hsYV9hbW0ucGhlLA0KICAgICAgICAgICAgICAgICAgICBram4ucGhlPWNobGFfa2puLnBoZSwNCiAgICAgICAgICAgICAgICAgICAgdG1wLmtqbj1jaGxhX3RtcC5ram4pDQoNCmxtc19jb21wYXJlLnN0YXRzIDwtIG1hcHBseShnbGFuY2UsIGxtc19jb21wYXJlKQ0KY29sbmFtZXMobG1zX2NvbXBhcmUuc3RhdHMpIDwtIG5hbWVzKGxtc19jb21wYXJlKQ0KbG1zX2NvbXBhcmUuc3RhdHMNCmBgYA0KDQojIyMjICoqLS1TZWxlY3RlZCBtdWx0aXBsZSByZWdyZXNzaW9uIG1vZGVsKioNCkJ5IGNvbXBhcmluZyB0aGUgbW9kZWxzIGFib3ZlLCAqKip0aGUgbW9kZWwgd2l0aCBhbGwgOCB2YXJpYWJsZXMgYWN0dWFsbHkgaGFkIHRoZSBoaWdoZXN0IGFkai1yLXNxdWFyZWQgdmFsdWUgY29tcGFyZWQgdG8gdGhlIG1vZGVscyB3aXRoIGxlc3MgcHJlZGljdG9yIHZhcmlhYmxlcyoqKi4gSG93ZXZlciwgaW4gdGhlIGNhc2UgdGhhdCBmZXdlciB2YXJpYWJsZXMgYXJlIGF2YWlsYWJsZSBmb3IgbWVhc3VyZW1lbnQsIEkgd291bGQgc2VsZWN0IHRoZSBmb2xsb3dpbmcgYmFzZWQgb24gY29tcGFyaXNvbiBvZiB2YWx1ZXMgb2YgdGhlIGFkai1yLXNxdWFyZSwgQUlDL0JJQywgcC12YWx1ZSwgYW5kIHRlc3Qgc3RhdGlzdGljLg0KDQoqICoqdGhlIDMtdmFyaWFibGUgbW9kZWwgYENobC1hIH4gQW1tb25pYSArIFBoZW9waHl0aW4gYWAqKg0KDQpUaGlzIG1vZGVsIGlzIGFibGUgdG8gZXhwbGFpbiA0NiUgb2YgdGhlIHZhcmlhdGlvbiBpbiBDaGwtYSBjb21wYXJlZCB0byA1NSUgd2hlbiB1c2luZyBhbGwgOCB2YXJpYWJsZXMuDQoNCkxldCdzIGNvbXBhcmUgdGhlIHJlc2lkdWFscyBhbmQgcHJlZGljdGVkIHZhbHVlcyBmb3IgdGhlIG1vZGVsIHdpdGggOCBwcmVkaWN0b3IgdmFyaWFibGVzIGFuZCB0aGUgbW9kZWwgYENobC1hIH4gQW1tb25pYSArIFBoZW9waHRpbiBhYC4NCg0KYGBge3J9DQoNCiMgcGxvdCByZXNpZHVhbHMNCg0KcGFyKG1mcm93ID0gYygyLCAyKSkNCnBsb3QoY2hsYV9hbGwsIHBjaCA9IDE2LCB3aGljaCA9IDEpDQpwbG90KGNobGFfYWxsLCBwY2ggPSAxNiwgd2hpY2ggPSAyKQ0KcGxvdChjaGxhX2FtbS5waGUsIHBjaCA9IDE2LCB3aGljaCA9IDEpDQpwbG90KGNobGFfYW1tLnBoZSwgcGNoID0gMTYsIHdoaWNoID0gMikNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANCg0KVG9wOiBhbGwgOCB2YXJpYWJsZXM7IEJvdHRvbTogQ2hsLWEgfiBBbW1vbmlhICsgUGhlb3BoeXRpbiBhLg0KDQpgYGB7cn0NCg0KIyBwbG90IHByZWRpY3RlZCB2cyBhY3R1YWwNCg0KcGFyKG1mcm93ID0gYygxLCAyKSkNCnBsb3QocHJlZGljdChjaGxhX2FsbCksd3FfbW9kZWwkYENobG9yb3BoeWxsIGFgLA0KICAgICB4bGFiPSJwcmVkaWN0ZWQiLHlsYWI9ImFjdHVhbCIsIG1haW4gPSJDaGwtYSB+IC4iKQ0KYWJsaW5lKGE9MCxiPTEpDQpwbG90KHByZWRpY3QoY2hsYV9hbW0ucGhlKSx3cV9tb2RlbCRgQ2hsb3JvcGh5bGwgYWAsDQogICAgIHhsYWI9InByZWRpY3RlZCIseWxhYj0iYWN0dWFsIiwgbWFpbiA9IkNobC1hIH4gQW1tb25pYSArIFBoZW9waHl0aW4gYSIpDQphYmxpbmUoYT0wLGI9MSkNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANCg0KIyMjIyAqKi0tQmVzdCBwcmVkaWN0b3IqKg0KVGhlIHNlbGVjdGVkIG11bHRpcGxlIHJlZ3Jlc3Npb24gbW9kZWwgaGFzIDIgdmFyaWFibGVzLiBJcyB0aGVyIG9uZSBiZXN0IHByZWRpY3RvciBmb3IgQ2hsLWEgY29uY2VudHJhdGlvbj8gSSBsb29rIGF0IDMgdmFyaWFibGVzOiBUZW1wZXJhdHVyZSwgQW1tb25pYSwgYW5kIFBoZW9waHl0aW4gYS4gVGhlc2UgMyB2YXJpYWJsZXMgaGF2ZSB0aGUgaGlnaGVzdCBjb3JyZWxhdGlvbiB2YWx1ZSB0byBDaGwtYSBiYXNlZCBvbiB0aGUgY29ycmVsYXRpb24gcGxvdC4NCmBgYHtyfQ0KIyBsbSBmb3IgZWFjaCBvZiB0aGUgMyB2YXJpYWJsZXMNCmNobGFfdG1wIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+IFRlbXBlcmF0dXJlLCBkYXRhID0gd3FfbW9kZWwpDQpjaGxhX2FtbSA8LSBsbShgQ2hsb3JvcGh5bGwgYWAgfiBgQW1tb25pYSAoRGlzc29sdmVkKWAsIGRhdGEgPSB3cV9tb2RlbCkNCmNobGFfcGhlIDwtIGxtKGBDaGxvcm9waHlsbCBhYCB+IGBQaGVvcGh5dGluIGFgLCBkYXRhID0gd3FfbW9kZWwpDQpgYGANCg0KYGBge3J9DQojIGNvbXBhcmUgbG1zIG9mIHRoZSAzIHZhcmlhYmxlcw0KbG1zX2Jlc3QgPC0gbGlzdChudWxsPWNobGFfbnVsbCwNCiAgICAgICAgICAgICAgICAgICAgYWxsPWNobGFfYWxsLA0KICAgICAgICAgICAgICAgICAgICB0bXA9Y2hsYV90bXAsDQogICAgICAgICAgICAgICAgICAgIGFtbT1jaGxhX2FtbSwNCiAgICAgICAgICAgICAgICAgICAgcGhlPWNobGFfcGhlKQ0KDQpsbXNfYmVzdC5zdGF0cyA8LSBtYXBwbHkoZ2xhbmNlLCBsbXNfYmVzdCkNCmNvbG5hbWVzKGxtc19iZXN0LnN0YXRzKSA8LSBuYW1lcyhsbXNfYmVzdCkNCmxtc19iZXN0LnN0YXRzDQpgYGANCg0KRnJvbSB0aGUgY29tcGFyaXNvbiwgSSB3b3VsZCBzYXkgdGhhdCAqKnRoZSBtb3N0IGltcG9ydGFudCB2YXJpYWJsZSBleHBsYWluaW5nIENobC1hIGlzIFBoZW9waHl0aW4gYSoqIHdoaWNoIGlzIGFibGUgdG8gZXhwbGFpbiAzNSUgb2YgdGhlIHZhcmlhYmlsaXR5IGluIENobC1hIGNvbXBhcmVkIHRvIDI1JSB3aXRoIFRlbXBlcmF0dXJlIGFuZCBvbmx5IDE2JSB3aXRoIEFtbW9uaWEuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIHBsb3QgcmVzaWR1YWxzDQoNCnBhcihtZnJvdz1jKDEsMikpDQpwbG90KGNobGFfcGhlLCBwY2g9MTYsIHdoaWNoPTEpDQpwbG90KGNobGFfcGhlLCBwY2g9MTYsIHdoaWNoPTIpDQpwYXIobWZyb3c9YygxLDEpKQ0KYGBgDQoNClRoZSBhcmUgc29tZXdoYXQgbm9ybWFsIGFuZCBkaXN0cmlidXRlZCBhbG9uZyB0aGUgMCBsaW5lIGFsdGhvdWdoIGltcHJvdmVtZW50cyBtYXkgbmVlZCB0byBiZSBkb25lLCBzdWNoIGFzIGludmVzdGlnYXRpb24gcG90ZW50aWFsIG91dGxpZXJzICg1NywgNDUsIGFuZCAzKS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgcGxvdCBwcmVkaWN0ZWQgdnMgYWN0dWFsDQoNCnBsb3QocHJlZGljdChjaGxhX3BoZSksd3FfbW9kZWwkYENobG9yb3BoeWxsIGFgLA0KICAgICB4bGFiPSJwcmVkaWN0ZWQiLHlsYWI9ImFjdHVhbCIsIG1haW4gPSAiQ2hsLWEgfiBQaGVvcGh5dGluIGEiKQ0KYWJsaW5lKGE9MCxiPTEpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgcGxvdCBDaGwtYSB2cyBQaGVvcGh5dGluIGEgYWN0dWFsIHZhbHVlcyB3aXRoIHByZWRpY3Rpb24gbGluZSBmcm9tIG1vZGVsDQoNCmdncGxvdCh3cV9tb2RlbCwgYWVzKHggPSBgUGhlb3BoeXRpbiBhYCwgeSA9IGBDaGxvcm9waHlsbCBhYCkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gcHJlZGljdChjaGxhX3BoZSkpLCBzaGFwZSA9IDEpDQpgYGANCg0KVGhlIHByZWRpY3RlZCB2YWx1ZXMgZnJvbSB0aGUgbW9kZWwgYXJlIHNvbWV3aGF0IHByZWRpY3RpbmcgdGhlIHRyZW5kIG9mIHRoZSBhY3R1YWwgdmFsdWVzLiANCg0KKioqDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPjJ8IFBhcmFsbGVsIFJlZ3Jlc3Npb248L3NwYW4+DQoqKioNCg0KIyMjIyAqKi0tRGF0YSBwcmVwYXJhdGlvbioqDQpgYGB7cn0NCiMgYWRkIHNlYXNvbnMNCg0Kd3FfbWVhbm1vbnRobHlfc2Vhc29uIDwtIHdxX21lYW5tb250aGx5DQoNCndxX21lYW5tb250aGx5X3NlYXNvbiRTZWFzb24gPC0gaWZlbHNlKHdxX21lYW5tb250aGx5X3NlYXNvbiRNb250aCA+IDkgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cV9tZWFubW9udGhseV9zZWFzb24kTW9udGggPCA1LCAid2V0IHNlYXNvbiIsICJkcnkgc2Vhc29uIikNCg0Kd3Ffc2Vhc29uIDwtIHdxX21lYW5tb250aGx5X3NlYXNvbiAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBzZWxlY3QoU2Vhc29uLCBldmVyeXRoaW5nKCkpICU+JQ0KICBzZWxlY3QoTW9udGgsIGV2ZXJ5dGhpbmcoKSkgJT4lDQogIHNlbGVjdChZZWFyLCBldmVyeXRoaW5nKCkpDQoNCndxX3NlYXNvbiRTZWFzb24gPC0gYXMuZmFjdG9yKHdxX3NlYXNvbiRTZWFzb24pDQpgYGANCg0KYGBge3J9DQojIGNyZWF0ZSBuZXcgZGF0YXNldCBmb3IgcGFyYWxsZWwgcmVncmVzc2lvbiBtb2RlbA0KDQp3cV9wcmxfbW9kZWwgPC0gc2VsZWN0KHdxX3NlYXNvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgYENobG9yb3BoeWxsIGFgLA0KICAgICAgICAgICAgICAgICAgICAgICBTZWFzb24sDQogICAgICAgICAgICAgICAgICAgICAgIGBQaGVvcGh5dGluIGFgKQ0KYGBgDQoNCiMjIyMgKiotLU1vZGVsIGNvbXBhcmlzb24qKg0KDQpgYGB7cn0NCiMgcGVyZm9ybSBsbXMNCg0KIyBDaGwtYSB+IHNlYXNvbg0KY2hsYV9zZWFzb24gPC0gbG0oYENobG9yb3BoeWxsIGFgIH4gU2Vhc29uLCBkYXRhID0gd3FfcHJsX21vZGVsKQ0KDQojIENobC1hIH4gUGhlb3BoeXRpbiBhDQpjaGxhX3BoZWEgPC0gbG0oYENobG9yb3BoeWxsIGFgIH4gYFBoZW9waHl0aW4gYWAsIGRhdGEgPSB3cV9wcmxfbW9kZWwpDQoNCiMgQ2hsLWEgfiBzZWFzb24gKyBwaGVvcGh5dGluIGENCmNobGFfc2Vhc29uLnBoZWEgPC0gbG0oYENobG9yb3BoeWxsIGFgIH4gU2Vhc29uICsgYFBoZW9waHl0aW4gYWAsIGRhdGEgPSB3cV9wcmxfbW9kZWwpDQpgYGANCg0KYGBge3J9DQojIGNvbXBhcmUgbW9kZWxzDQpsbXNfcHJsIDwtIGxpc3Qoc2Vhc29uPWNobGFfc2Vhc29uLCBwaGVhPWNobGFfcGhlYSwgc2Vhc29uLnBoZWE9Y2hsYV9zZWFzb24ucGhlYSkNCg0KbG1zX3BybC5zdGF0cyA8LSBtYXBwbHkoZ2xhbmNlLCBsbXNfcHJsKQ0KY29sbmFtZXMobG1zX3BybC5zdGF0cykgPC0gbmFtZXMobG1zX3BybCkNCmxtc19wcmwuc3RhdHMNCmBgYA0KVGhlIGFkZGl0aW9uIG9mIHRoZSBzZWFzb24gY2F0ZWdvcnkgZG9lcyBzZWVtIHRvIGltcHJvdmUgdGhlIG1vZGVsLiBUaGUgcGFyYWxsZWwgbW9kZWwgaXMgYWJsZSB0byBleHBsYWluIDQzJSBvZiB0aGUgdmFyaWF0aW9uIHdoaWxlIHRoZSBtb2RlbCB3aXRoIG9ubHkgUGhlb3BoeXRpbiBhIGFzIHRoZSB2YXJpYWJsZSBpcyBvbmx5IGFibGUgdG8gZXhwbGFpbiAzNSUgb2YgdGhlIHZhcmlhdGlvbi4NCg0KIyMjIyAqKi0tUmVzaWR1YWxzKioNCg0KYGBge3J9DQojIHBsb3QgcmVzaWR1YWxzDQoNCnBhcihtZnJvdz1jKDIsMykpDQoNCnBsb3QoY2hsYV9zZWFzb24sIHBjaD0xNiwgd2hpY2g9MSkNCnBsb3QoY2hsYV9waGVhLCBwY2g9MTYsIHdoaWNoPTEpDQpwbG90KGNobGFfc2Vhc29uLnBoZWEsIHBjaD0xNiwgd2hpY2g9MSkNCg0KcGxvdChjaGxhX3NlYXNvbiwgcGNoPTE2LCB3aGljaD0yKQ0KcGxvdChjaGxhX3BoZWEsIHBjaD0xNiwgd2hpY2g9MikNCnBsb3QoY2hsYV9zZWFzb24ucGhlYSwgcGNoPTE2LCB3aGljaD0yKQ0KDQpwYXIobWZyb3c9YygxLDEpKQ0KDQpgYGANCkxlZnQ6IENobC1hIH4gc2Vhc29uOyBNaWRkbGU6IENobC1hIH4gUGhlb3BoeXRpbiBhOyBSaWdodDogUGFyYWxsZWwgbW9kZWwuDQoNCiMjIyMgKiotLVBsb3QqKg0KDQpgYGB7cn0NCiMgZXh0cmFjdCBpbnRlcmNlcHQgYW5kIHNsb3BlIHZhbHVlcyB0byBnZW5lcmF0ZSByZWdyZXNzaW9uIGxpbmVzDQoNCnNlYXNvbl9jb2VmIDwtIGRhdGEuZnJhbWUodChjb2VmKGNobGFfc2Vhc29uKSkpDQpjb2xuYW1lcyhzZWFzb25fY29lZikgPC0gYygiaW50ZXJjZXB0IiwgInNsb3BlIikNCnNlYXNvbl9jb2VmDQoNCnBoZWFfY29lZiA8LSBkYXRhLmZyYW1lKHQoY29lZihjaGxhX3BoZWEpKSkNCmNvbG5hbWVzKHBoZWFfY29lZikgPC0gYygiaW50ZXJjZXB0IiwgInNsb3BlIikNCnBoZWFfY29lZg0KDQpzZWFzb24ucGhlYV9jb2VmIDwtIGRhdGEuZnJhbWUodChjb2VmKGNobGFfc2Vhc29uLnBoZWEpKSkNCmNvbG5hbWVzKHNlYXNvbi5waGVhX2NvZWYpIDwtIGMoImludGVyY2VwdCIsICJzbG9wZS5zZWFzb24iLCAic2xvcGUucGhlIikNCnNlYXNvbi5waGVhX2NvZWYNCmBgYA0KDQpgYGB7cn0NCiMgcGxvdCBDaGwtYSB2cyBQaGVvcGh5dGluIGEgd2l0aCByZWdyZXNzaW9uIGxpbmVzDQoNCnBsb3Qod3FfcHJsX21vZGVsJGBQaGVvcGh5dGluIGFgLCB3cV9wcmxfbW9kZWwkYENobG9yb3BoeWxsIGFgLCANCiAgICAgeGxhYiA9ICJQaGVvcGh5dGluIGEiLA0KICAgICB5bGFiID0gIkNobG9yb3BoeWxsIGEiLA0KICAgICBjb2wgPSB3cV9wcmxfbW9kZWwkU2Vhc29uLA0KICAgICBwY2ggPSAxNiwNCiAgICAgbWFpbiA9ICJCeSBTZWFzb24gKGRyeSBzZWFzb246IGJsYWNrLCBkcnkgc2Vhc29uOiByZWQpIikNCmFibGluZShyZWcgPSBjaGxhX3BoZWEsIGx0eSA9IDIpDQphYmxpbmUoYSA9IHNlYXNvbi5waGVhX2NvZWYkaW50ZXJjZXB0LCBiID0gc2Vhc29uLnBoZWFfY29lZiRzbG9wZS5waGUsIGNvbCA9ICJibHVlIikNCmBgYA0KVGhlIGJsdWUgbGluZSBpcyB0aGUgcmVncmVzc2lvbiBsaW5lIGZyb20gdGhlIHBhcmFsbGVsIG1vZGVsIHdoaWxlIHRoZSBkYXNoZWQgYmxhY2sgbGluZSBpcyB0aGUgcmVncmVzc2lvbiBsaW5lIGZvciB0aGUgYENobC1hIH4gUGhlb3BoeXRpbiBhYCBtb2RlbC4gQWx0aG91Z2ggbm90IGVudGlyZWx5IGNsZWFyIGZyb20gdGhlIHBsb3QsIGl0IHNlZW1zIGFzIHRob3VnaCB0aGUgcGFyYWxsZWwgbW9kZWwgaXMgYWNjb3VudGluZyBmb3IgZm9yIHRoZSBkcnkgc2Vhc29uIHBvaW50cyBjb21wYXJlZCB0byB0aGUgdW5pdmFyaWF0ZSBtb2RlbC4gVGhpcyBtYXkgYmUgYmVjYXVzZSBvZiB0aGUgaW5mbHVlbmNlIG9mIHRoZSBzZWFzb24gdmFyaWFibGUgaW4gdGhlIHBhcmFsbGVsIG1vZGVsLiBUaGUgcGxvdCBhbHNvIHNob3dzIGhvdyB0aGUgZHJ5IHNlYXNvbiBtYXkgaGF2ZSBhIGhpZ2hlciBtZWFuIHZhbHVlIHRoYW4gdGhlIHdldCBzZWFzb24gYXMgaXQncyB2YWx1ZXMgc2VlbSB0byBiZSBoaWdoZXIgdGhhbiB2YWx1ZXMgZnJvbSB0aGUgd2V0IHNlYXNvbi4NCg0KKioqDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPjN8IEdpdEh1YiBMaW5rPC9zcGFuPg0KKioqDQoNCmh0dHBzOi8vZ2l0aHViLmNvbS9jbnB3L2VzMjA3X2h3Nw0K